package cn.bxshey.auth.service.impl;

import cn.bxshey.auth.domain.dto.LoginDto;
import cn.bxshey.auth.domain.pojo.*;
import cn.bxshey.auth.domain.vo.UserDetails;
import cn.bxshey.auth.mapper.*;
import cn.bxshey.auth.service.LoginService;
import cn.bxshey.general.constant.JwtConstant;

import cn.bxshey.general.enums.ResultEnum;
import cn.bxshey.general.exception.BusinessException;
import cn.bxshey.general.util.HttpUtils;
import cn.bxshey.general.util.JwtUtils;
import cn.bxshey.redis.constant.RedisConstant;
import cn.bxshey.redis.utils.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @作者：不想说话而已
 * @Date：2023/11/30 16:45
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class WxLoginServiceImpl implements LoginService {

    @Autowired
    HttpUtils httpUtils;

    @Resource
    UserMapper userMapper;

    @Resource
    AsyncService asyncService;

    @Resource
    RoleUserMapper roleUserMapper;

    @Resource
    RedisUtils redisUtils;

    @Resource
    RestTemplate restTemplate;

    @Resource


    @Value("${baby.wechat.appid}")
    private String APP_ID; //appid

    @Value("${baby.wechat.secret}")
    private String SECRET; //密钥
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";


    @Override
    public Map<String, Object> login(Map<String, String> info) throws JsonProcessingException {

        //远程微信获取openid
        String openid = getOpenid(info.get("js_code"));
        //如果微信授权失败
        if (Objects.isNull(openid)) {
            throw new BusinessException(ResultEnum.ERROR_WX_AUTH);
        }

        //授权成功返回
        //1.查询用户信息，根据openid
        User user = userMapper.selectByOpenid(openid);

        //为空则新增用户信息
        if (Objects.isNull(user)) {
            User newUser = new User(UUID.randomUUID().toString(), openid);
            userMapper.insertUser(newUser);
            roleUserMapper.insert(new RoleUser(1, newUser.getUserId()));
            user = newUser;
        } else {
            //更新登录时间
            asyncService.recordLoginTime(user.getUserId());
        }

        //2.查询权限信息
        List<Permissions> permissions = userMapper.selectUserPermissions((user.getUserId()));

        //3.获取当前的ip地址信息
        Map<String, String> httpInfo = httpUtils.getHttpInfo();

        //4.封装现有信息，生成token
        Map<String, String> userInfo = new HashMap<>();
        userInfo.put("uid", String.valueOf(user.getUserId()));
        userInfo.put("username", user.getUsername());
        userInfo.put("ip", httpInfo.get("ip"));
        String token = JwtUtils.createToken(userInfo);

        //5.过滤取出权限信息
        String[] collect = permissions.stream()
                .map(Permissions::getUrl).toArray(String[]::new);

        //6.权限存入redis
        redisUtils.addSetValue(RedisConstant.PERMISSIONS, userInfo.get("uid"), collect);
        //7.登录成功返回 token等信息
        Map<String, Object> userDetails = new HashMap<>();
        UserDetails loginVo = new UserDetails();
        Optional.ofNullable(loginVo.getPhone()).ifPresent(s -> {
            String substring = loginVo.getPhone().substring(0, 3);
            loginVo.setPhone(substring + "********");
        });
        BeanUtils.copyProperties(user, loginVo);
        userDetails.put("access_tokens", token);
        userDetails.put("userInfo", loginVo);
        return userDetails;

    }

    //远程请求微信，获取openid 用户唯一标识
    public String getOpenid(String code) {
        //请求路径
        String url = WX_LOGIN + "?appid=" + APP_ID
                + "&secret=" + SECRET
                + "&js_code=" + code
                + "&grant_type=authorization_code";

        //远程请求微信 ，请求微信授权
        String forObject = restTemplate.getForObject(url, String.class);
        WxChat wxChat = JSON.parseObject(forObject, WxChat.class);
        return Objects.isNull(wxChat) ? null : wxChat.getOpenid();
    }


}
